import 'dart:convert';

import 'package:common_utils/common_utils.dart';
import 'package:catguard/config/env_config.dart';
import 'package:catguard/utils/singleton_manager.dart';
import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:catguard/config/config.dart';
import 'package:get_storage/get_storage.dart';
import 'package:crypto/crypto.dart';

import '../utils/user_utils.dart';

///
/// Dio框架的封装
///
class Request {
  // 配置 Dio 实例
  static final BaseOptions _options = BaseOptions(
    baseUrl: Env.envConfig.baseUrl,
    connectTimeout: const Duration(seconds: 30),
    receiveTimeout: const Duration(seconds: 60),
    // contentType: 'application/json',
    contentType: 'multipart/form-data',
    // contentType: Headers.formUrlEncodedContentType,
  );

  // 创建 Dio 实例
  static final Dio _dio = Dio(_options);

  // _request 是核心函数，所有的请求都会走这里
  static Future<T> _request<T>(String apiName, {String? method, data}) async {
    data ??= <String, String>{};

    // data['_app_ver'] = SingletonManager().appVer;
    // data['_os'] = SingletonManager().os;
    // data['_os_ver'] = SingletonManager().osVer;
    // data['_model'] = SingletonManager().model;
    // data['_brand'] = SingletonManager().brand;

    final box = GetStorage();
    LogUtil.v('${Env.envConfig.baseUrl}$apiName', tag: '请求域名=');
    LogUtil.v(jsonEncode(data), tag: '请求参数=');

    String token = box.read("token") ?? '';
    Map<String, dynamic> head = {
      'app-key': Config.appKey,
      'user-token': token,
      'uuid': SingletonManager().udid,
      'language': SingletonManager().appLanguage,
      '_os': SingletonManager().os,
      '_os_ver': SingletonManager().osVer,
      '_app_ver': SingletonManager().appVer,
    };
    LogUtil.v(head.toString(), tag: '请求Header=');
    _dio.options.headers.addAll(head);

    try {
      late Response response;
      if (method == 'get') {
        response = await _dio.get(apiName, queryParameters: data);
      } else {
        response = await _dio.post(apiName, data: data);
      }
      LogUtil.v(response, tag: '$apiName返回数据=');
      if (response.statusCode == 200 || response.statusCode == 201) {
        try {
          var result = response.data;
          if (result['code'] != 1) {
            if (result['msg'].isNotEmpty) {
              EasyLoading.showInfo(result['msg'].toString());
            }
          }
          return result;
        } catch (e) {
          LogUtil.v(e, tag: '解析数据异常');
          return Future.error('解析数据异常');
        }
      } else {
        LogUtil.v(response.statusCode, tag: 'HTTP错误，状态码为：');
        EasyLoading.showInfo('HTTP错误，状态码为：${response.statusCode}');
        _handleHttpError(response.statusCode!);
        return Future.error('HTTP错误');
      }
    } on DioException catch (e, s) {
      LogUtil.v('接口请求异常=$apiName', tag: "response");
      EasyLoading.showInfo(_dioError(e));
      return Future.error(_dioError(e));
    } catch (e, s) {
      LogUtil.v(e, tag: '未知异常');
      return Future.error('未知异常');
    }
  }


  // 处理 Dio 异常
  static String _dioError(DioException error) {
    LogUtil.v(error.toString(), tag: "响应错误明细");
    switch (error.type) {
      case DioExceptionType.connectionTimeout:
        return "网络连接超时，请检查网络设置";
      case DioExceptionType.receiveTimeout:
        return "服务器异常，请稍后重试！";
      case DioExceptionType.badResponse:
        return "服务器异常，请稍后重试！";
      case DioExceptionType.cancel:
        return "请求已被取消，请重新请求";
      default:
        return "Dio异常";
    }
  }

  // 处理 Http 错误码
  static void _handleHttpError(int errorCode) {
    String message;
    switch (errorCode) {
      case 400:
        message = '请求语法错误';
        break;
      case 401:
        message = '未授权，请登录';
        break;
      case 403:
        message = '拒绝访问';
        break;
      case 404:
        message = '请求出错';
        break;
      case 408:
        message = '请求超时';
        break;
      case 500:
        message = '服务器异常';
        break;
      case 501:
        message = '服务未实现';
        break;
      case 502:
        message = '网关错误';
        break;
      case 503:
        message = '服务不可用';
        break;
      case 504:
        message = '网关超时';
        break;
      case 505:
        message = 'HTTP版本不受支持';
        break;
      default:
        message = '请求失败，错误码：$errorCode';
    }
    EasyLoading.showError(message);
  }

  static Future<T> get<T>(String apiName, {Map? data}) {
    return _request(apiName, method: 'get', data: data);
  }

  static Future<T> post<T>(String apiName, {Map? data}) {
    return _request(apiName, method: 'post', data: data);
  }

// ///dio 实现文件上传
// static fileUplod(String apiUrl, String localImagePath) async {
//   LogUtil.v(apiUrl, tag: "上传接口");
//   LogUtil.v(localImagePath, tag: "上传文件本地路径");
//   Map<String, dynamic> map = {};
//   map["file"] = await MultipartFile.fromFile(localImagePath);
//
//   ///通过FormData
//   FormData formData = FormData.fromMap(map);
//
//   ///发送post
//   Response response = await _dio.post(
//     apiUrl,
//     data: formData,
//     onSendProgress: (int progress, int total) {
//       LogUtil.v("当前进度是 $progress 总进度是 $total");
//     },
//   );
//
//   ///服务器响应结果
//   var data = response.data;
//   LogUtil.v(data, tag: "上传结果");
//   return data;
// }

}
